/**
 *  fat_get_last_cluster_of_file()
 *  vrati posledni cluster souboru (jeste pred 0xFFF)
 *  IN:   <cluster>   - pocatecni cluster souboru
 *  OUT:  <c_last>    - posledni cluster
 */
unsigned int fat_get_last_cluster_of_file(unsigned int cluster) {
  unsigned int c_last = cluster;
  while(1) {
    fat_get_next_cluster(&cluster);
    if(fat_end(cluster))
      return c_last;
    c_last = cluster;
  }

  return (signed int)(-1);
}

/**
 *  fat_get_last_cluster_of_actual_dir()
 *  funkce, ktera zjisti posledni cluster aktualni slozky
 *  IN:  [void]
 *  OUT: cluster
 */
unsigned int fat_get_last_cluster_of_actual_dir(void) {
  unsigned int i   = 0, cycle = 0, page = 0,
               pos = 0, last  = 0;
  DirectoryEntry far *sfile = mem_alloc(sizeof(DirectoryEntry), KERNEL_SEGMENT);

  last = _dir_actual->c_actual;
  while((i = find_file(sfile, i)) != (unsigned int)END_OF_DIR)
    pos++;
  page = (--pos/16);

  /* prepocitame pozici ve strukture slozky podle pozice */
  for(cycle=0; cycle < page; cycle++) {
    fat_get_next_cluster(&(_dir_actual->c_actual));    /* dalsi cluster */
    last = _dir_actual->c_actual;
  }
  _dir_actual->c_actual = _dir_actual->c_start;
  mem_free(sfile);
  return last;
}

/**
 *  fat_edit_entry_by_cluster()
 *  edituje zaznam souboru v seznamu souboru podle clusteru a pozice v nem
 *  IN:   <sfile>    - struktura souboru
 *        <cluster>   - cluster, kde se nachazi polozka souboru
 *        <pos>       - pozice v clusteru, kde se soubor nachazi
 *  OUT:  [void]
 */
void fat_edit_entry_by_cluster(DirectoryEntry far *sfile, unsigned int cluster, unsigned int pos) {
  char far *buffer = mem_alloc(0x200, KERNEL_SEGMENT);
  floppyread((_fat->data_start_sector + (cluster - 2)), 1, buffer);
  memcpy(buffer+(pos*32), sfile, 32);
  floppywrite((_fat->data_start_sector + (cluster - 2)), 1, buffer);
  mem_free(buffer);
  return;
}

/**
 *  fat_entry_assign()
 *  nastavi do <memfile> informace o souboru
 *  IN:  <memfile>  - misto v pameti, kam se nahraji informace o souboru ve formatu FAT
 *       <filename> - nazev souboru, ve FAT formatu
 *       <attr>     - atribut souboru (readonly, dir, archive...)
 *  OUT: <memfile>  - misto v pameti, kam se nahraji informace o souboru ve formatu FAT
 */
char far *fat_entry_assign(char far *memfile, char far *filename, char attr) {
  static struct Time t;
  static struct Date d;
  int i;
  for(i=0; i<32; i++)
    memfile[i] = '\0';
  memcpy(memfile, filename, 11);

  time_get(&t);
  date_get(&d);

  ((DirectoryEntry far *)(memfile))->attr      = attr;

  /* cas */
  ((DirectoryEntry far *)(memfile))->time.min  = t.min;
  ((DirectoryEntry far *)(memfile))->time.hour = t.hour;
  ((DirectoryEntry far *)(memfile))->time.sec  = t.sec / 2;

  /* datum */
  ((DirectoryEntry far *)(memfile))->date.day   = d.day;
  ((DirectoryEntry far *)(memfile))->date.month = d.month;
  ((DirectoryEntry far *)(memfile))->date.year  = d.year - 1980;

  return memfile;
}

/**
 *  fat_associate_entry()
 *  asociuje hodnoty souboru z pameti <mem> do struktury [DirectoryEntry]
 *  IN:   <mem>   - cast pameti, odkud se bude kopirovat
 *        <sfile> - DirEntry
 *  OUT:  [void]
 */
void fat_associate_entry(const char far *mem, DirectoryEntry far *sfile) {
  memcpy(sfile, mem, 32);
  fat_get_real_filename(
    sfile->name,
    sfile->ext,
    sfile->realname
  );
  return;
}
